﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using KSAWPFExtensions;
using System.Windows.Media.Animation;
using System.Windows.Media.Media3D;
using KSATouch;

using HelixToolkit.Wpf;

namespace KSAWPFDemo.ThreeDManipulation
{
    /// <summary>
    /// Interaction logic for ThreeDBrowser.xaml
    /// </summary>
    public partial class ThreeDBrowser : UserControl
    {
        private Plane3D ContourPlane;
        Dictionary<int, Color> colors = new Dictionary<int, Color>();
        Random rand;

        /// <summary>
        /// Gets or sets the model.
        /// </summary>
        /// <value>The model.</value>
        public Model3D Model { get; set; }

        public Transform3DGroup transforms;
        public AxisAngleRotation3D yRotationAngle;
        public AxisAngleRotation3D xRotationAngle;

        private KSAWPFExtensions.KSAWPFWindow mainWindow;

        public ThreeDBrowser()
        {
            //todo: error checking for file not found...
            InitializeComponent();
            rand = new Random((int)DateTime.Now.Ticks);

            this.Loaded += ThreeDBrowser_Loaded;
           
        }

        void ThreeDBrowser_Loaded(object sender, RoutedEventArgs e)
        {
            mainWindow = KSAWPFWindow.GetWindow(this) as KSAWPFWindow;
            mainWindow.FrameReady += MainWindow_FrameReady;

            transforms = new Transform3DGroup();

            yRotationAngle = new AxisAngleRotation3D(new Vector3D(0, 1, 0), 0);
            xRotationAngle = new AxisAngleRotation3D(new Vector3D(1, 0, 0), 0);


            RotateTransform3D yRotation = new RotateTransform3D(yRotationAngle);
            RotateTransform3D xRotation = new RotateTransform3D(xRotationAngle);

            transforms.Children.Add(yRotation);
            transforms.Children.Add(xRotation);

            ship.Transform = transforms;
            //ship.Visibility = System.Windows.Visibility.Hidden;
            //AddContours(ship, 7, 7, 7);
            
            

        }
        /// <summary>
        /// This sample code is taken directly from the Contours sample in the Helix toolkit
        /// </summary>
        /// <param name="model1"></param>
        /// <param name="o"></param>
        /// <param name="m"></param>
        /// <param name="n"></param>
        private void AddContours(Visual3D model1, int o, int m, int n)
        {
            var bounds = Visual3DHelper.FindBounds(model1, Transform3D.Identity);
            for (int i = 1; i < n; i++)
            {
                this.ContourPlane = new Plane3D(new Point3D(0, 0, bounds.Location.Z + bounds.Size.Z * i / n), new Vector3D(0, 0, 1));
                Visual3DHelper.Traverse<GeometryModel3D>(model1, this.AddContours);
            }
            for (int i = 1; i < m; i++)
            {
                this.ContourPlane = new Plane3D(new Point3D(0, bounds.Location.Y + bounds.Size.Y * i / m, 0), new Vector3D(0, 1, 0));
                Visual3DHelper.Traverse<GeometryModel3D>(model1, this.AddContours);
            }
            for (int i = 1; i < o; i++)
            {
                this.ContourPlane = new Plane3D(new Point3D(bounds.Location.X + bounds.Size.X * i / o, 0, 0), new Vector3D(1, 0, 0));
                Visual3DHelper.Traverse<GeometryModel3D>(model1, this.AddContours);
            }
        }

        private void AddContours(GeometryModel3D model, Transform3D transform)
        {
            var p = ContourPlane.Position;
            var n = ContourPlane.Normal;
            var segments = MeshGeometryHelper.GetContourSegments(model.Geometry as MeshGeometry3D, p, n).ToList();
            foreach (var contour in MeshGeometryHelper.CombineSegments(segments, 1e-6).ToList())
            {
                if (contour.Count == 0)
                    continue;
                viewPort.Children.Add(new TubeVisual3D { Diameter = 0.03, Path = new Point3DCollection(contour), Fill = Brushes.Green });
            }
        }


        void MainWindow_FrameReady(object Sender, FrameReadyEventArgs e)
        {

            if (e.CurrentContacts.Count > 0)
                return;

            Contact hand = e.HoveringContacts.FirstOrDefault();
            if (hand != null)
            {
                debug.Content = "XTilt: " + hand.XTilt + "\r\n YTilt: " + hand.YTilt + " Z: " + hand.ContactZHeight;
                int angle = 10;

                if (hand.YTilt < 0 - angle)
                {
                    yRotationAngle.Angle+=2;
                }
                if (hand.YTilt > angle)
                {
                    yRotationAngle.Angle-=2;
                }
                // Handle 'x' tilt
                if (hand.XTilt > angle)
                {                    
                    //xRotationAngle.Angle++;
                }
                if (hand.XTilt < 0 - angle)
                {                    
                   //xRotationAngle.Angle--;
                }
                
            }

        }

        Color GetRandomeColor()
        {
            Color r = new Color();
            r.R = (byte)rand.Next(20, 255);
            r.G = (byte)rand.Next(20, 255);
            r.B = (byte)rand.Next(20, 255);
            r.A = 255;
            return r;
        }

        public void DrawEllipse(double x, double y, Color color,int height,int width)
        {
            Ellipse ellipse = new Ellipse();
            ellipse.Height = height;
            ellipse.Width = width;
            ellipse.Fill = new SolidColorBrush(color);
            Canvas.SetTop(ellipse, y);
            Canvas.SetLeft(ellipse, x);
            mainCanvas.Children.Add(ellipse);
            DoubleAnimation da = new DoubleAnimation(0, new Duration(TimeSpan.FromSeconds(1)));
            da.BeginTime = TimeSpan.FromSeconds(1);
            da.Completed += delegate(object sender2, EventArgs e2)
            {
                mainCanvas.Children.Remove(ellipse);
            };

            ellipse.BeginAnimation(Ellipse.OpacityProperty, da);
        }

        public void DrawEllipse(double x, double y, Color color)
        {
            DrawEllipse(x, y, color, 50, 50);            
        }

        private void Grid_TouchDown_1(object sender, TouchEventArgs e)
        {
            //Debug.Content = "Touchdown : " + e.GetTouchPoint(null).Position.ToString();
            Color color = GetRandomeColor();
            colors.Add(e.TouchDevice.Id, color);
            DrawEllipse(e.GetTouchPoint(null).Position.X + 25, e.GetTouchPoint(null).Position.Y + 25, color);
        }

        private void Grid_TouchUp_1(object sender, TouchEventArgs e)
        {
           //Debug.Content = "Touchup : " + e.GetTouchPoint(null).Position.ToString();
            colors.Remove(e.TouchDevice.Id);
        }

        private void Grid_TouchMove_1(object sender, TouchEventArgs e)
        {
            try
            {
                //Debug.Content = "TouchMove : " + e.GetTouchPoint(null).Position.ToString();
                Color color = colors[e.TouchDevice.Id];
                DrawEllipse(e.GetTouchPoint(null).Position.X, e.GetTouchPoint(null).Position.Y, color);
            }
            catch (Exception)
            { 
                
            }
        }
    }    
}
